class Watcher {
    constructor(vm, expr, callback) {
        this.vm = vm;
        this.expr = expr;
        this.callback = callback;
        this.oldValue = this.getOldValue();
    }
    getOldValue() {
        Dep.target = this;
        const oldValue = compileUtil.getValue(this.expr, this.vm);
        Dep.target = null;
        return oldValue;
    }
    update() {
        const newValue = compileUtil.getValue(this.expr, this.vm);
        if (newValue !== this.oldValue) {
            this.callback(newValue);
            this.oldValue=newValue;//修改旧值
        }
    }

}

class Dep {
    constructor() {
        this.subs = []
    }
    addSub(wactcher) {
        this.subs.push(wactcher)
    }
    notify() {
        this.subs.forEach(wactcher => wactcher.update())
    }
}
class Observer {
    constructor(data) {
        this.observe(data)
    }
    observe(data) {
        if (data && typeof data === 'object') {
            const keys = Object.keys(data)
            for (let i = 0; i < keys.length; i++) {
                this.defineReactive(data, keys[i], data[keys[i]])
            }
        }
    }
    defineReactive(data, key, value) {
        //监听子属性
        this.observe(value);
        const dep = new Dep();
        Object.defineProperty(data, key, {
            enumerable: true,
            configurable: true,
            get: function () {
                //订阅数据变化，Dep中添加观察者
                Dep.target&&dep.addSub(Dep.target)
                return value
            },
            set: (newVlaue) => {
                if (newVlaue !== value) {
                    // 如果外界直接修改对象 则对新修改的值重新观察 如重新赋值对象操作
                    this.observe(newVlaue);
                    value = newVlaue;
                     // 通知变化
                    dep.notify();
                }
            }
        })

    }
}